import easing from './easing'
import {color} from 'zrender'
class AnimatePlayer {
    isPaused = true
    loop = false
    duration = 0
    // 动画列表
    ticks = []
    // 当前时间，控制动画
    now = 0
    // 帧率，控制now的变化量
    fps = 40
    constructor() {}

    seek(time) {
        this.now = time;
        this.updateAttr();
    }

    // 添加动画：叫什么名字，什么元素，什么属性（{style:{},shape:{}），持续时间： [开始时间，结束时间]
    // 注意，每个动画过程都应包含起始值和结束值 如 x: [50, 150]  fill:['#ccc', '#f00']
    add(name, el, attrObj, startTime, endTime, ease = 'linear') {
        if(this.ticks.some(d=>d.name === name)){
            console.warn(name + ':该动画名称已经存在')
        }
        let item = {
            name,
            el,
            attrObj,
            startTime,
            endTime,
            easing: (easing[ease] ? easing[ease] : easing['linear'])
        }
        this.ticks.push(item)
    }

    get(){
        return this.ticks;
    }

    remove(name) {
        this.ticks = this.ticks.filter(d => (d.name !== name))
    }

    // 根据now值，更新所有元素的展示效果
    updateAttr() {
        let elRate = {}
        this.ticks.forEach(tick => {
            let rate = 100;
            if(tick.startTime > this.now){
                rate = Math.abs(this.now - tick.startTime)
            }else if(tick.endTime < this.now){
                rate = Math.abs(this.now - tick.startTime)
            }else {
                rate = 0;
            }
            if((elRate[tick.el.id]===undefined) || (rate < elRate[tick.el.id])){
                elRate[tick.el.id] = rate;
                let percent;
                if (this.now < tick.startTime) percent = 0;
                else if (this.now > tick.endTime) percent = 1;
                else percent = tick.easing((this.now - tick.startTime) / (tick.endTime - tick.startTime))
                tick.el.attr(this.getAttrObj(tick.attrObj, percent))
            }
        })
    }

    getAttrObj(orginObject, percent) {
        if (orginObject == null || typeof orginObject !== 'object') {
            return;
        }
        const resultObject = {}
        //深度遍历需要创建栈
        const stack = [];
        for (let key of Object.keys(orginObject)) {
            stack.push({
                key: key,//属性名
                value: orginObject[key],//value属性记录当前节点下属数据
                parent: resultObject//记录节点在resultObject中的位置
            })
        }

        while (stack.length) {
            const currentNode = stack.pop();
            const parent = currentNode.parent;
            const currentKey = currentNode.key;
            const currentValue = currentNode.value;
            //若是无下属对象，返回其值
            if (currentValue instanceof Array) {
                parent[currentKey] = this.getValueByPercent(currentValue, percent);
            } else {
                //若下属值是对象，将子节点压入栈中
                parent[currentKey] = Object.prototype.toString.call(currentValue) === '[object Array]' ? [] : {};
                for (let key of Object.keys(currentValue)) {
                    stack.push({
                        key: key,
                        value: currentValue[key],
                        parent: parent[currentKey]
                    })
                }
            }
        }
        return resultObject;
    }

    // 根据数据的起始、结束值和当前动画运动的百分数，确定最终值
    getValueByPercent(val, per){
        // 异常的不可转换的值
        if(!(val instanceof Array) || val.length < 2){
            return null
        }
        let result;
        if(typeof(val[0]) === 'number'){
            // 数值类型，直接计算
            result = val[0] + (val[1] - val[0]) * per;
        }else if(val[0] instanceof Array){
            if(val[0][0] instanceof Array){
                // 支持数组
                let arr = []
                val[0].forEach((a, i)=>{
                    let b = val[1][i]
                    let temp = []
                    a.forEach((v, i)=>{
                        temp.push(a[i] + (b[i] - a[i]) * per)
                    })
                    arr.push(temp)
                })
                result = arr
            }else{
                // 支持数组
                let arr = []
                val[0].forEach((a, i)=>{
                    let b = val[1][i]
                    arr.push(a + (b - a) * per)
                })
                result = arr
            }
        }else if(typeof val[0] === 'string' && ['#', 'rgb'].some(d=>val[0].includes(d))){
            // 支持颜色
            let p = per;
            if(p > 1) p = 1;
            else if(p < 0) p = 0;
            result = color.lerp(p,[val[0], val[1]])
        }
        if(val[2] && typeof val[2] === 'function'){
            return val[2](result)
        }
        return result;
    }
}

export default AnimatePlayer;